from django.db import transaction
from rest_framework import viewsets, status
from rest_framework.decorators import action, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser, AllowAny
from django.contrib.auth import authenticate
from django.db.models import Q

from stock.models import StockIn, StockOut
from .models import Employee
from .serializers import EmployeeSerializer, EmployeeCreateSerializer, EmployeeLoginSerializer
from .authentication import generate_token
from warehouse_system.pagination import StandardResultsSetPagination

class EmployeeViewSet(viewsets.ModelViewSet):
    queryset = Employee.objects.all()
    serializer_class = EmployeeSerializer
    permission_classes = [IsAuthenticated]
    pagination_class = StandardResultsSetPagination

    def get_permissions(self):
        if self.action == 'login':
            return [AllowAny()]
        if self.action in ['create', 'destroy', 'status']:
            return [IsAdminUser()]  # 仅管理员可以创建、删除和更改状态
        if self.action in ['update', 'partial_update']:
            return [IsAuthenticated()]  # 认证用户可以更新
        return [IsAuthenticated()]

    def get_serializer_class(self):
        if self.action == 'create':
            return EmployeeCreateSerializer
        return EmployeeSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        # 获取新创建的员工对象
        employee = serializer.instance

        # 使用 EmployeeSerializer 序列化员工对象
        employee_data = EmployeeSerializer(employee).data

        # 构建自定义响应格式
        response_data = {
            "code": 1,
            "data": {
                "id": employee_data['id'],
                "username": employee_data['username'],
                "name": employee_data['name'],
                "phone": employee_data['phone'],
                "sex": employee_data['sex'],
                "id_number": employee_data['id_number'],
                "role": employee_data['role'],
                "status": employee_data['status']
            }
        }

        headers = self.get_success_headers(serializer.data)
        return Response(response_data, status=status.HTTP_201_CREATED, headers=headers)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()

        try:
            with transaction.atomic():
                # 更新或删除相关的 StockIn 和 StockOut 实例
                StockIn.objects.filter(create_user=instance).delete()
                StockOut.objects.filter(create_user=instance).delete()

                # 执行删除操作
                self.perform_destroy(instance)

            # 构建自定义响应格式
            response_data = {
                "code": 1,
                "data": None
            }

            return Response(response_data, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({"detail": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        # 使用 EmployeeSerializer 序列化更新后的员工对象
        employee_data = EmployeeSerializer(instance).data

        # 构建自定义响应格式
        response_data = {
            "code": 1,
            "data": {
                "id": employee_data['id'],
                "username": employee_data['username'],
                "name": employee_data['name'],
                "phone": employee_data['phone'],
                "sex": employee_data['sex'],
                "id_number": employee_data['id_number'],
                "role": employee_data['role'],
                "status": employee_data['status']
            }
        }

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return Response(response_data)

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get('name')
        if name:
            queryset = queryset.filter(
                Q(name__icontains=name) | 
                Q(username__icontains=name)
            )
        return queryset

    @action(detail=False, methods=['post'])
    def login(self, request):
        serializer = EmployeeLoginSerializer(data=request.data)
        if not serializer.is_valid():
            return Response({'code': 0, 'msg': '参数错误'}, status=status.HTTP_400_BAD_REQUEST)
        
        username = serializer.validated_data['username']
        password = serializer.validated_data['password']
        
        user = authenticate(username=username, password=password)
        if not user:
            return Response({'code': 0, 'msg': '用户名或密码错误'}, status=status.HTTP_400_BAD_REQUEST)
        
        if not user.is_active:
            return Response({'code': 0, 'msg': '账号已被禁用'}, status=status.HTTP_400_BAD_REQUEST)
        
        token = generate_token(user)
        return Response({
            'code': 1,
            'data': {
                'id': user.id,
                'username': user.username,
                'name': user.name,
                'role': user.role,
                'token': token
            }
        })

    @action(detail=False, methods=['post'])
    def logout(self, request):
        return Response({'code': 1, 'data': None})

    @action(detail=True, methods=['post'])
    def status(self, request, pk=None):
        status = request.data.get('status')
        if status not in [0, 1]:
            return Response({'code': 0, 'msg': '状态值无效'}, status=status.HTTP_400_BAD_REQUEST)
        
        employee = self.get_object()
        employee.status = status
        employee.save()
        return Response({'code': 1, 'data': None}) 